package com.wsoft.cms.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wsoft.cms.entity.CmsAnnouncementEntity;
import com.wsoft.cms.entity.CmsAnnouncementSignEntity;
import com.wsoft.cms.enums.SummaryTypeEnum;
import com.wsoft.cms.manager.CmsAnnouncementManager;
import com.wsoft.cms.manager.CmsAnnouncementSignManager;
import com.wsoft.cms.manager.CmsAnnouncementSummaryManager;
import com.wsoft.cms.mapper.CmsAnnouncementSignMapper;
import com.wsoft.cms.query.sign.SignListQuery;
import com.wsoft.cms.query.sign.SignQuery;
import com.wsoft.cms.service.ICmsAnnouncementSignService;
import com.wsoft.cms.vo.sign.AnnoSignVO;
import com.wsoft.core.exception.Asserts;
import com.wsoft.core.service.CommonMemberService;
import com.wsoft.core.utils.LoginUserUtil;
import com.wsoft.core.utils.SqlAuthDisableHolder;
import com.wsoft.core.vo.MemberVO;
import com.wsoft.enums.PublishStatusEnum;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户通告报名记录表 服务实现类
 * </p>
 *
 * @author juiet
 * @since 2024年11月27日 10:38:58
 */
@Service
public class CmsAnnouncementSignServiceImpl extends ServiceImpl<CmsAnnouncementSignMapper, CmsAnnouncementSignEntity> implements ICmsAnnouncementSignService {

    @Resource
    private CmsAnnouncementSignManager signManager;
    @Resource
    private CmsAnnouncementSummaryManager summaryManager;
    @Resource
    private CmsAnnouncementManager announcementManager;
    @Resource
    private CommonMemberService memberService;

    /**
     * 报名/取消报名
     * @param query
     * @param isSign
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean sign(SignQuery query, boolean isSign) {
        Long annoId = query.getAnnoId();
        CmsAnnouncementEntity entity = announcementManager.getById(annoId);
        //校验
        signCheck(entity);
        if(isSign){
            //报名
            CmsAnnouncementSignEntity signEntity = buildSignEntity(annoId);
            signManager.save(signEntity);
            //计数
            summaryManager.addCount(annoId, SummaryTypeEnum.SIGN.getType(),1);
        }else{
            //取消报名
            signManager.cancelSign(annoId,LoginUserUtil.getUserInfo().getLoginUserVO().getId());
            //计数
            summaryManager.addCount(annoId, SummaryTypeEnum.SIGN.getType(),-1);
        }
        return true;
    }

    @Override
    public PageInfo listSign(SignListQuery query) {
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        SqlAuthDisableHolder.open();
        PageInfo pageInfo = PageInfo.of(signManager.listSign(query));
        List<CmsAnnouncementSignEntity> list = pageInfo.getList();
        List<AnnoSignVO> voList = new ArrayList<>();
        if(CollUtil.isNotEmpty(list)){
            List<MemberVO> memberList = memberService.getMemberList();
            Map<Long, MemberVO> collect = memberList.stream().collect(Collectors.toMap(MemberVO::getId, memberVO -> memberVO));
            for (CmsAnnouncementSignEntity signEntity : list) {
                AnnoSignVO convert = Convert.convert(AnnoSignVO.class, signEntity);
                MemberVO memberVO = collect.get(convert.getMemberId());
                convert.setMemberName( memberVO == null? "":memberVO.getName());
                convert.setMemberPhoto( memberVO == null? "":memberVO.getPhoto());
                voList.add(convert);
            }
        }
        SqlAuthDisableHolder.close();
        pageInfo.setList(voList);
        return pageInfo;
    }


    // ################################## 私有方法  ##################################


    /**
     * 构建 signEntity
     * @param annoId
     * @return
     */
    private CmsAnnouncementSignEntity buildSignEntity(Long annoId){

        Long memberId = LoginUserUtil.getUserInfo().getLoginUserVO().getId();
        CmsAnnouncementSignEntity sign = signManager.getByAnnoIdAndMemberId(annoId, memberId);
        if(sign != null && sign.getSignFlag() == 1){
            //已经报名
            Asserts.fail("[cms.sign.again.error]");
        }
        CmsAnnouncementSignEntity signEntity = new CmsAnnouncementSignEntity();
        signEntity.setAnnoId(annoId);
        signEntity.setMemberId(LoginUserUtil.getUserInfo().getLoginUserVO().getId());
        signEntity.setSignFlag(1);
        signEntity.setSignTime(LocalDateTime.now());
        return signEntity;
    }

    /**
     * 校验能够报名
     * @param startTime
     * @param endTime
     * @return
     */
    public void signCheck(CmsAnnouncementEntity entity) {
        if(entity == null || !PublishStatusEnum.PUBLISH.getType().equals(entity.getSendStatus()) || entity.getIsSign() == 0){
            //当前不允许报名
            Asserts.fail("[cms.sign.error]");
        }

        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();

        LocalDateTime startTime = entity.getStartTime();
        LocalDateTime endTime = entity.getEndTime();
        // 判断是否在报名时间段内
        boolean isAfterStartTime = startTime == null || now.isAfter(startTime) || now.isEqual(startTime);
        boolean isBeforeEndTime = endTime == null || now.isBefore(endTime) || now.isEqual(endTime);

        // 如果同时满足条件，则可以报名
         if(!(isAfterStartTime && isBeforeEndTime)){
             //当前不允许报名
             Asserts.fail("[cms.sign.error]");
         }
    }
}
